package cn.lyjuan.first.netty.demo._2_netty;

import cn.lyjuan.first.netty.demo._2_netty.selector.AbstractNIOSelector;

import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;

public class NIOPool
{
    private Executor bossEx;

    private Executor workerEx;

    private AtomicInteger bossIndex;

    private AtomicInteger workerIndex;

    private AbstractNIOSelector[] bosses;

    private AbstractNIOSelector[] workeres;

    /**
     * 初始化 boss 相关属性
     *
     * @param boss  boss注册线程池
     * @param count boss数量
     * @return
     */
    public NIOPool initBoss(Executor boss, int count)
    {
        this.bossEx = boss;
        this.bossIndex = new AtomicInteger();
        this.bosses = new AbstractNIOSelector[count];

        for (int i = 0; i < count; i++)
            this.bosses[i] = new BossSelector().init("Boss Selector#-" + i, this.bossEx, this);

        return this;
    }

    /**
     * 初始化worker相关属性
     *
     * @param workerEx worker注册线程池
     * @param count    worker数量
     * @return
     */
    public NIOPool initWorker(Executor workerEx, int count)
    {
        this.workerEx = workerEx;
        this.workerIndex = new AtomicInteger();
        this.workeres = new AbstractNIOSelector[count];

        for (int i = 0; i < count; i++)
            this.workeres[i] = new WorkerSelector().init("Worker Selector#-" + i, this.workerEx, this);

        return this;
    }

    /**
     * 获取boss
     *
     * @return
     */
    public AbstractNIOSelector nextBoss()
    {
        return bosses[Math.abs(bossIndex.incrementAndGet() % bosses.length)];
    }

    public AbstractNIOSelector nextWorker()
    {
        return workeres[Math.abs(workerIndex.incrementAndGet() % workeres.length)];
    }

    /**
     * 线程池中运行boss
     *
     * @param run
     */
    public void bossRun(Runnable run)
    {
        bossEx.execute(run);
    }

    /**
     * 线程池中运行worker
     *
     * @param run
     */
    public void workerRun(Runnable run)
    {
        workerEx.execute(run);
    }
}
